
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvTimer.h"
#include "contiki.h"

#define WIRE_DATA_HIGH()	DrvGPIO_SetBit(E_GPE, 8)
#define WIRE_DATA_LOW()	DrvGPIO_ClrBit(E_GPE, 8)
#define WIRE_OUTPUT_MODE()		{DrvGPIO_Close(E_GPE, 8); DrvGPIO_Open(E_GPE, 8, E_IO_OUTPUT);DrvGPIO_SetBit(E_GPE, 8);}

#define WIRE_DATA()				DrvGPIO_GetBit(E_GPE, 8)
#define WIRE_INPUT_MODE()		{DrvGPIO_SetBit(E_GPE, 8); DrvGPIO_Close(E_GPE, 8); DrvGPIO_Open(E_GPE, 8, E_IO_INPUT);}


static int8_t dah11_get_byte(uint8_t *pu8Data)
{
	unsigned long long u64Time;
	uint8_t u8i;
	*pu8Data = 0x00;
	for(u8i=0x80; u8i !=0; u8i = u8i>>1)
	{
		//bit start
		u64Time = clock_usec();
		printf("s %x\r\n", u8i);
		while(WIRE_DATA() == 0)		
		{
			uint16_t diff = clock_usec() - u64Time;
			printf("err %d->%d\n", __LINE__,diff);
		}
		

		clock_delay_usec(20);	//delay 20 us to decode data
		u64Time = clock_usec();
		while(WIRE_DATA() == 1)
		{
			if(clock_usec() - u64Time > 20)
			{
				break;
			}
		}
		
		if(clock_usec() - u64Time > 20)
		{
			//bit 1
			*pu8Data |= u8i;
		}

		//wait cur data finish
		while(WIRE_DATA() == 1);
		{
			uint16_t diff = clock_usec() - u64Time;
			printf("err %d->%qd\n", __LINE__,diff);
		}

		printf("t %x\r\n", u8i);
	}

	return 0;
}

void DH11_Init(void)
{
		
}

int8_t DH11_GetInfo(uint8_t *puT, uint8_t *puH)
{
	unsigned long long u64Time;
	uint8_t u8Data;

	WIRE_OUTPUT_MODE();

	//Host start
	WIRE_DATA_LOW();
	clock_delay_usec(18000);
	WIRE_DATA_HIGH();

	//write dht11
	WIRE_INPUT_MODE();
	clock_delay_usec(40);

	if(WIRE_DATA() == 0)	//dht11 ack
	{
		//wait ack finish
		u64Time = clock_usec();
		while(WIRE_DATA() == 0)
		{
			if(clock_usec() - u64Time > 80)
			{
				printf("err %d\n", __LINE__);
				return -1;
			}
		}

		u64Time = clock_usec();
		while(WIRE_DATA() == 1)
		{
			if(clock_usec() - u64Time > 80)
			{
				printf("err %d\n", __LINE__);
				return -1;
			}
		}

		if(clock_usec() - u64Time > 70)		//start decode data
		{
			if(dah11_get_byte(&u8Data) == -1)
			{
				return -1;
			}
			*puT = u8Data;
			
			if(dah11_get_byte(&u8Data) == -1)
			{
				return -1;
			}

			if(dah11_get_byte(&u8Data) == -1)
			{
				return -1;
			}
			*puH = u8Data;

			if(dah11_get_byte(&u8Data) == -1)
			{
				return -1;
			}
			return 0;
		}
	}
	printf("err %d\n", __LINE__);
	return -1;
}

